第一章作业

能够输入五个连接词符号

据说这些个符号也可以在各种输入法的表情符号里找到,那样时会很方便哈!下面我来总结一下我发现的方法

∧ 合取 unicode十六进制:2227
∨ 析取 unicode十六进制:2228
¬ 非 unicode十六进制:00AC(不区分大小写) Ascii十进制: 172

以上三种符号均可以在进入WPS后点击菜单栏的插入--符号--其他符号选项中进行添加,自己找这些符号也可以在弹出的框框里面选择编码以及对应的值直接搜索到。

↔ 等价
→ 蕴涵

以上两种符号可以在插入--公式--插入新公式中找到。

示例是在word里面进行的,经我测试ppt中操作是一样的,但是在excel中插入新公式我也不知道为什么不能点,可以直接从word/ppt复制粘贴。

判断是否为合式公式

  这个问题有好多方法,递归,栈,数什么高深的东西,但显然我这种小小白是绝对做不出来的,当然只能用暴力的方法了,咳咳,那谁不是曾经说过吗,暴力出奇迹。python还不是很熟悉,我先用c++来实现。
  我的方法是遍历字符串中的每一个字符,通过对不同情况的分析,进行分类处理。
  我们来看看这个问题,要判断是否为合式公式,那我们首先应该了解一下何为合式公式。
  合式公式:将命题变项用联结词和圆括号按照一定的逻辑关系联结起来的符号串称为合式公式。
  由于这几个符号的输入比较麻烦,我们这里做一下简单的替换
& 合取 | 析取 ! 非 - 蕴含 = 等价
例如p&q !p !(p&q)&s|r均为合式公式,而qwp q&&d等均不是合式公式。
代码实现(具体分情况请参考注释)

#include<bits/stdc++.h>
using namespace std;
char s[100000];
int main()
{
    bool flag;
    scanf("%s",s);
    flag=1;//定义一个布尔类型的变量,初始赋值为1,代表是合式公式,每种条件下的判断中若发现不是合式公式,就改变flag的值为0,代表不是合式公式。
    if(s[0]==')'||s[0]=='&'||s[0]=='-'||s[0]=='='||s[0]=='|')//若第一个字符就是联结词或者右括号,显然不是合式公式。
    {
        puts("Not well formed!");
        return 0;
    }
    for(int i=0;i<strlen(s);i++)//这里的这种情况判断的是如果有两个字母(即原子命题)在一起,显然也不是合式公式。
    {
        if(s[i]>=65&&s[i]<=90||s[i]>=97&&s[i]<=122)
        {
            if(s[i+1]>=65&&s[i+1]<=90||s[i+1]>=97&&s[i+1]<=122)
            {
                puts("Not well formed!");
                return 0;
            }
        }
    }
    for(int i=1;i<strlen(s);i++)//这里的这种情况判断的是如果有两个联结词(不包括非)在一起,显然也不是合式公式。
    {
        if(s[i]=='&'||s[i]=='|'||s[i]=='-'||s[i]=='=')
        {
            if(s[i+1]=='&'||s[i+1]=='|'||s[i+1]=='-'||s[i+1]=='='||s[i-1]=='&'||s[i-1]=='|'||s[i-1]=='-'||s[i-1]=='=')
            {
                flag=0;
                break;
            }
        }
        else if(s[i]=='!')//如果非后面加的是联结词,显然也不是合式公式。
        {
            if(s[i+1]=='&'||s[i+1]=='|'||s[i+1]=='-'||s[i+1]=='=')
            {
                flag=0;
                break;
            }
            if(s[i+1]=='!'||s[i-1]=='!')//如果几个非连在一起可以看成是一个。
                break;
            else if(s[i+1]>122||s[i+1]<65)
            {
                flag=0;
                break;
            }
            else if(s[i+1]>90&&s[i+1]<97)//此处判断的是非后面是否加的是原子命题。
            {
                flag=0;
                break;
            }
        }
    }
    stack<char> sta;//设定一个栈用来检测左右括号的匹配性。
    for(int i=0;i<strlen(s);i++)
    {
        if(s[i]==')'&&sta.empty())//如果是右括号且此时栈空(说明此右括号的前面没有与之配的左括号,所以不是合式公式)。
        {
            flag=0;
            break;
        }
        if(s[i]=='(')//如果是左括号就入栈。
        {
            sta.push(s[i]);
        }
        if(s[i]==')'&&!sta.empty())//如果是右括号,且栈不空就将栈顶的左括号除去。
        {
            sta.pop();
        }
    }
    if(!sta.empty())//如果字符串循环完毕且栈中还有元素,说明有左括号不存在与之对应的右括号,即不为合式公式。
    flag=0;
    if(flag)     puts("Well formed");
    else     puts("Not well informed");
    return 0;
}

求合式公式的层次

给出任意命题公式的成真赋值

给出任意命题公式的成假赋值

判断任一命题公式的公式类型